/*
 * LocationServer.h
 *
 *  Created on: 2013. 8. 5.
 *      Author: jjaehuny
 */

#ifndef PROJECTZ_NPROXY_LOCATIONSERVER_H_
#define PROJECTZ_NPROXY_LOCATIONSERVER_H_

#include <Dispatcher/Session.h>
#include <Dispatcher/Timer.h>
#include <Dispatcher/NSession/State.h>
#include <Network/Static.h>
//#include "../../../LocationServer/idl/Location.h"
#include "../../../protocol/Location.h"

#include "Session.h"

namespace ProjectZ { namespace NProxy {

#define CMD_CONNECT				0x0001
#define CMD_DISCONNECT 			0x0002

class LocationServer : public Session::IOwner, public::Dispatcher::Timer::IObserver
{
public:
	class Msg
	{
	public:
		static void OnOpenAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnCloseAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnRegistAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnUnRegistAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnChatSyn(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnChatAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnRecallSyn(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnRecallAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnKickUser(Dispatcher::Session* pSession, ::Network::Packet * pPacket );
		static void OnTradeItemSoldoutSyn(Dispatcher::Session* pSession, ::Network::Packet * pPacket);
		static void OnSetMainCharacterInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket);
		static void OnGetMainCharacterInfoAck(Dispatcher::Session* pSession, ::Network::Packet * pPacket);
		static void OnGetMainCharacterInfoAck_V2(Dispatcher::Session* pSession, ::Network::Packet * pPacket);
	};

public:
	class State : public ::Dispatcher::NSession::State
	{
	public:
		State()
		{
			AddCommand( LocationOpenAck::MSG_ID, Msg::OnOpenAck);
			AddCommand( LocationCloseAck::MSG_ID, Msg::OnCloseAck);
			AddCommand( RegistAck::MSG_ID, Msg::OnRegistAck);
			AddCommand( UnRegistAck::MSG_ID, Msg::OnUnRegistAck);
			AddCommand( ChatSyn::MSG_ID, Msg::OnChatSyn);
			AddCommand( ChatAck::MSG_ID, Msg::OnChatAck);
			AddCommand( RecallSyn::MSG_ID, Msg::OnRecallSyn);
			AddCommand( RecallAck::MSG_ID, Msg::OnRecallAck);
			AddCommand( KickUser::MSG_ID, Msg::OnKickUser);
			AddCommand( TradeItemSoldoutSyn::MSG_ID, Msg::OnTradeItemSoldoutSyn);
			AddCommand( SetMainCharacterInfoAck::MSG_ID, Msg::OnSetMainCharacterInfoAck);
			AddCommand( GetMainCharacterInfoAck::MSG_ID, Msg::OnGetMainCharacterInfoAck);
			AddCommand( GetMainCharacterInfoAck_V2::MSG_ID, Msg::OnGetMainCharacterInfoAck_V2);
		}

		~State() {}
	};

public:
	LocationServer();
	virtual ~LocationServer();

	bool 	Connect(int idx, std::string strIP, int port);
	void	OnDisconnect();
	virtual bool OnTime(int id, void* param);

	template<class T> void SendMessage(const T& msg)
	{
		::Network::Packet* pPacket = ::Network::GETPACKETPOOL()->SEND_NEW();
		char* pBuf = pPacket->GetOffsetPtr();
		if(false == msg.Store(&pBuf))
		{
			::Network::GETPACKETPOOL()->SEND_DEL(pPacket);
			return;
		}
		pPacket->SetLen(msg.Size());
		pPacket->MakePacketNoTail(T::MSG_ID);

		_pSession->SendPacket(pPacket, true);
	}

	int 		GetIdx() { return _idx; }

private:
	void	setTime();

private:
	//::Dispatcher::Session * _pSession;
	Session * _pSession;
	bool		_bConnect;
	int 		_idx;
	::Network::Session::Info _clsInfo;
};

} /*NProxy*/ } /*ProjectZ*/

#endif /* PROJECTZ_NPROXY_LOCATIONSERVER_H_ */
